package com.example.mobilesafe.activity;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.example.mobilesafe.R;
import com.example.mobilesafe.dao.VirusDao;
import com.example.mobilesafe.domain.ScanInfo;
import com.example.mobilesafe.utils.MD5Util;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class AnitVirusActivity extends AppCompatActivity {

    private static final int SCANING = 100;
    private static final int SCANING_FINISH = 101;
    private ImageView iv_scanning;
    private TextView tv_name;
    private ProgressBar pb_bar;
    private LinearLayout ll_add_text;
    private int index = 0;
    private List<ScanInfo> virusScanInfoList;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case SCANING:
                    // 1.显示正在扫描应用的名称
                    ScanInfo scanInfo = (ScanInfo) msg.obj;
                    tv_name.setText(scanInfo.getName());
                    // 2.在线性布局中添加一个正在扫描应用的TextView
                    TextView textView = new TextView(getApplicationContext());
                    if (scanInfo.isVirus()){
                        // 是病毒
                        textView.setTextColor(Color.RED);
                        textView.setText("发现病毒：" + scanInfo.getName());
                    }else {
                        // 不是病毒
                        textView.setTextColor(Color.BLACK);
                        textView.setText("扫描安全：" + scanInfo.getName());
                    }
                    ll_add_text.addView(textView,0); // 索引为0代表每次都在最上面添加
                    break;
                case SCANING_FINISH:
                    tv_name.setText("扫描完成");
                    iv_scanning.clearAnimation(); // 停止在控件上正在执行的旋转
                    // 告知用户要去卸载包含了病毒的应用
                    uninstallVirus();
                    break;
            }
        }
    };

    /**
     * 卸载包含了病毒的应用
     */
    private void uninstallVirus() {
        for (ScanInfo scanInfo : virusScanInfoList) {
            String packageName = scanInfo.getPackageName();
            // 隐式Intent启动卸载功能
            Intent intent = new Intent("android.intent.action.DELETE");
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setData(Uri.parse("package:" + packageName));
            startActivity(intent);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_anit_virus);

        // 初始化UI
        initUI();

        // 初始化动画
        initAnimation();

        // 检测病毒
        checkVirus();
    }

    /**
     * 初始化UI
     */
    private void initUI() {
        iv_scanning = findViewById(R.id.iv_scanning);
        tv_name = findViewById(R.id.tv_name);
        pb_bar = findViewById(R.id.pb_bar);
        ll_add_text = findViewById(R.id.ll_add_text);
    }

    /**
     * 初始化动画
     */
    private void initAnimation() {
        RotateAnimation rotateAnimation= new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(1000);
        // 指定动画一直旋转
        rotateAnimation.setRepeatCount(RotateAnimation.INFINITE);
        // 指定旋转后的位置，保持动画执行结束后的状态
        rotateAnimation.setFillAfter(true);
        // 执行旋转动画
        iv_scanning.startAnimation(rotateAnimation);
    }

    /**
     * 检测手机上的病毒
     */
    private void checkVirus() {
        new Thread(){
            @Override
            public void run() {
                // 获取数据库中所有病毒的md5码
                List<String> virusList = VirusDao.getVirusList();
                // 获取手机上面的所有应用程序签名文件的md5码
                // 1.获取包管理对象
                PackageManager packageManager = getPackageManager();
                // 2.获取所有应用程序所对应的签名文件，参数为(已安装应用的签名文件 + 卸载应用的残余文件)
                List<PackageInfo> installedPackages = packageManager.getInstalledPackages(PackageManager.GET_SIGNATURES + PackageManager.GET_UNINSTALLED_PACKAGES);
                // 记录病毒的List
                virusScanInfoList = new ArrayList<>();
                List<ScanInfo> scanInfoList= new ArrayList<>(); // 记录所有应用的List
                // 设置进度条最大值
                pb_bar.setMax(installedPackages.size());
                // 3.遍历应用集合
                for (PackageInfo packageInfo : installedPackages) {
                    ScanInfo scanInfo = new ScanInfo();
                    Signature[] signatures = packageInfo.signatures;
                    // 4.获取签名文件数组的第一位，然后进行md5算法转换，将此md5和数据库中的md5进行比对
                    Signature signature = signatures[0];
                    String s = signature.toCharsString();
                    // 32位字符串，16进制字符(0-f)
                    String encoder = MD5Util.encoder(s);
                    // 5.比对应用是否为病毒
                    if (virusList.contains(encoder)){
                        // 6.记录病毒
                        scanInfo.setVirus(true);
                        virusScanInfoList.add(scanInfo);
                    }else {
                        scanInfo.setVirus(false);
                    }
                    // 7.维护对象的包名，以及应用名称
                    scanInfo.setPackageName(packageInfo.packageName);
                    scanInfo.setName(packageInfo.applicationInfo.loadLabel(packageManager).toString());
                    scanInfoList.add(scanInfo);
                    // 8.更新进度条的百分比
                    index++;
                    pb_bar.setProgress(index);
                    // 9.模拟耗时操作
                    try {
                        Thread.sleep(50  + new Random().nextInt(100));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 10.在子线程中发送消息，告知主线程更新UI（1：顶部扫描应用的名称，2：扫描过程中往线性布局添加view）
                    Message message = Message.obtain();
                    message.what = SCANING;
                    message.obj = scanInfo;
                    mHandler.sendMessage(message);
                }
                // 11.当扫描所有应用后，将文本置为“扫描完成”
                Message message = Message.obtain();
                message.what = SCANING_FINISH;
                mHandler.sendMessage(message);
            }
        }.start();
    }
}